﻿using MCPlatform.Dxf.Entities;
using MCPlatform.Dxf.Factories;
using MCPlatform.Dxf.Readers;
using MCPlatform.Dxf.Utils;
using MCPlatform.MotionLib.Base.AssitantClass;
using MCPlatform.MotionLib.Base.Environment;
using Microsoft.Win32;
using netDxf.Entities;
using Panuon.WPF.UI;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;
using System.Windows.Navigation;
using System.Windows.Shapes;
using static System.Formats.Asn1.AsnWriter;


namespace MCPlatform.Dxf.Views
{
    /// <summary>
    /// DxfView.xaml 的交互逻辑
    /// </summary>
    public partial class DxfView : UserControl
    {

        System.Windows.Point lastPosition = new System.Windows.Point();

        public  PathEntityFactoryManager pathEntityFactoryManager = new PathEntityFactoryManager();

        public static Dictionary<Type, List<PathEntityBase>> EntitiesWithPaths =
           new Dictionary<Type, List<PathEntityBase>>();


        public List<string> pathPropertyNames;

        private string? _fileName;



        public string FileName
        {
            get { return (string)GetValue(FileNameProperty); }
            set { SetValue(FileNameProperty, value); }
        }

        // Using a DependencyProperty as the backing store for FileName.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty FileNameProperty =
            DependencyProperty.Register("FileName", typeof(string), typeof(DxfView), new PropertyMetadata(default));



        public DxfView()
        {
            InitializeComponent();

            //获取列名
            pathPropertyNames = GetPropertyNames(new PathEntityBase());
            
            //生成列名
            GenerateColumns();

            
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            if (FileName != null && FileName != string.Empty)
            {
                LoadDxf(FileName);
                Autofill();
            }
        }

        private void LoadDxf(string fileName)
        {

            string filePath = Paths.DxfSavePaths;

            _fileName = fileName;

            // 构建目标文件路径
            string targetFilePath = System.IO.Path.Combine(filePath, fileName+".dxf");

            if (!File.Exists(targetFilePath))
            {
                targetFilePath = System.IO.Path.Combine(filePath, fileName + ".dwg");
            }          

            if (File.Exists(targetFilePath))
            {
                this.canvas.Children.Clear();
                canvas.Scale = 1;
                canvas.Offset = new System.Windows.Point();
                DxfReader dxfReader = new DxfReader();
                dxfReader.ReadFromFile(targetFilePath);
                var dxfEntities = dxfReader.entitiesWithPaths;

                EntitiesWithPaths = dxfEntities;
                foreach (var path in dxfEntities.Values)
                {

                    foreach (var shape in path)
                    {
                        if (shape.Shape != null)
                        {
                            this.canvas.Children.Add(shape.Shape);
                        }

                    }

                }

                //查询是否有保存的DXF信息
                var models = ReadConfigData.GetParaConfigs<DxfCharacterModel>(Paths.DxfConfigPaths);
                if (models != null)
                {
                    foreach (var model in models)
                    {
                        if (model.ControlName == _fileName)
                        {
                            if (model?.PunchesHandles?.Length > 0)
                            {
                                foreach (var p in model.PunchesHandles)
                                {
                                    SetEntityPunchPoint(dxfEntities, p, true);
                                }
                            }

                            if (model?.VisionHandles?.Length > 0)
                            {
                                foreach (var p in model.VisionHandles)
                                {
                                    SetEntityVisionPoint(dxfEntities, p, true);
                                }
                            }



                            if (model?.CuttingHandles?.Length > 0)
                            {
                                foreach (var p in model.CuttingHandles)
                                {
                                    SetEntityCuttingPoint(dxfEntities, p, true);
                                }
                            }


                        }
                    }
                }

                GeneratorItemSource(dxfEntities);



            }
            else
            {
                MessageBox.Show("文件获取失败");
            }
        }

        private void Load_Click(object sender, RoutedEventArgs e)
        {
            
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Title = "Load a dxf File";
            if (openFileDialog.ShowDialog() == true)
            {
                string fileName = openFileDialog.FileName;

                _fileName = System.IO.Path.GetFileNameWithoutExtension(fileName);

               

                if (File.Exists(fileName))
                {
                    this.canvas.Children.Clear();
                    canvas.Scale = 1;
                    canvas.Offset = new System.Windows.Point();
                    DxfReader dxfReader = new DxfReader();
                    dxfReader.ReadFromFile(fileName);
                    var dxfEntities = dxfReader.entitiesWithPaths;

                    EntitiesWithPaths = dxfEntities;
                    foreach (var path in dxfEntities.Values)
                    {

                        foreach (var shape in path)
                        {
                            if (shape.Shape !=null)
                            {
                                this.canvas.Children.Add(shape.Shape);
                            }
                            
                        }

                    }

                    //查询是否有保存的DXF信息
                    var models = ReadConfigData.GetParaConfigs<DxfCharacterModel>(Paths.DxfConfigPaths);
                    if (models!=null)
                    {
                        foreach (var model in models)
                        {
                            if (model.ControlName == _fileName)
                            {
                                if (model?.PunchesHandles?.Length > 0)
                                {
                                    foreach (var p in model.PunchesHandles)
                                    {
                                        SetEntityPunchPoint(dxfEntities, p, true);
                                    }
                                }

                                if (model?.VisionHandles?.Length > 0)
                                {
                                    foreach (var p in model.VisionHandles)
                                    {
                                        SetEntityVisionPoint(dxfEntities, p, true);
                                    }
                                }

                                if (model?.CuttingHandles?.Length > 0)
                                {
                                    foreach (var p in model.CuttingHandles)
                                    {
                                        SetEntityCuttingPoint(dxfEntities, p, true);
                                    }
                                }


                            }
                        }
                    }

                    GeneratorItemSource(dxfEntities);

                    
                   
                }
                else
                {
                    MessageBox.Show("文件获取失败");
                }
            }
        }


        private void Canvas_MouseMove(object sender, MouseEventArgs e)
        {
            var height = this.canvas.ActualHeight + FirstRowHeight.Height.Value;
            System.Windows.Point position = e.GetPosition(this);
            lastPosition = position;
            CoordinatesTextBlock.Text = $"坐标：X: {position.X:F3}mm, Y: {height-position.Y:F3}mm";
        }

       
        private void Autofill()
        {
            if (canvas.Children.Count == 0)
                return;

            double minLeft = double.MaxValue;
            double maxLeft = double.MinValue;
            double minTop = double.MaxValue;
            double maxTop = double.MinValue;


            foreach (var entitys in EntitiesWithPaths.Values)
            {
                foreach (var entity in entitys)
                {
                    double left = entity.StartPoint.X;
                    double right = entity.EndPoint.X;
                    double top = entity.StartPoint.Y;
                    double bottom = entity.EndPoint.Y;


                    minLeft = Math.Min(minLeft, left);
                    maxLeft = Math.Max(maxLeft, right);
                    minTop = Math.Min(minTop, top);
                    maxTop = Math.Max(maxTop, bottom);
                }
               

            }

            //foreach (var child in canvas.Children)
            //{
                //if (child is System.Windows.Shapes.Line line)
                //{
                //    if (double.IsNaN(line.ActualWidth) || double.IsNaN(line.ActualHeight) ||
                //         double.IsNaN(Canvas.GetLeft(line)) || double.IsNaN(Canvas.GetTop(line)))
                //    {
                //        continue;
                //    }
                //    double left = Math.Min(Canvas.GetLeft(line), Canvas.GetLeft(line) + line.X2 - line.X1);
                //    double right = Math.Max(Canvas.GetLeft(line), Canvas.GetLeft(line) + line.X2 - line.X1);
                //    double top = Math.Min(Canvas.GetTop(line), Canvas.GetTop(line) + line.Y2 - line.Y1);
                //    double bottom = Math.Max(Canvas.GetTop(line), Canvas.GetTop(line) + line.Y2 - line.Y1);

                //    minLeft = Math.Min(minLeft, left);
                //    maxLeft = Math.Max(maxLeft, right);
                //    minTop = Math.Min(minTop, top);
                //    maxTop = Math.Max(maxTop, bottom);
                //}
                // if (child is System.Windows.Shapes.Shape shape) // Handle other types of shapes
                //{
                //    if (double.IsNaN(shape.ActualWidth) || double.IsNaN(shape.ActualHeight) ||
                //         double.IsNaN(Canvas.GetLeft(shape)) || double.IsNaN(Canvas.GetTop(shape)))
                //    {
                //        continue;
                //    }
                //    double left = Canvas.GetLeft(shape);
                //    double right = Canvas.GetLeft(shape) + shape.ActualWidth;
                //    double top = Canvas.GetTop(shape);
                //    double bottom = Canvas.GetTop(shape) + shape.ActualHeight;

                //    minLeft = Math.Min(minLeft, left);
                //    maxLeft = Math.Max(maxLeft, right);
                //    minTop = Math.Min(minTop, top);
                //    maxTop = Math.Max(maxTop, bottom);
                //}
                // Add more else if blocks for other types of shapes if needed
           // }

            // Calculate scale
            double scale = Math.Min(canvas.ActualWidth / (maxLeft - minLeft), canvas.ActualHeight / (maxTop - minTop)) * 0.95;



            if (scale > 0)
            {
                // Adjust scale
                canvas.Scale = scale;

                // Adjust offset
                canvas.Offset = new System.Windows.Point(minLeft * scale - (canvas.ActualWidth - (maxLeft - minLeft) * scale) / 2,
                    minTop * scale - (canvas.ActualHeight - ((maxTop - minTop) * scale)) / 2);

                
            }


            //if (scale > 0)
            //{
            //    // Adjust scale
            //    // canvas.Scale = scale;
            //    double s = 1;
            //    canvas.Scale = s;

            //    // Adjust offset
            //    // double offsetX = minLeft * scale - (canvas.ActualWidth - (maxLeft - minLeft) * scale) / 2;
            //    // double offsetY = minTop * scale - (canvas.ActualHeight - ((maxTop - minTop) * scale)) / 2;

            //    double leftDis = maxLeft - minLeft;
            //    double midPos = (maxTop - minTop)/2+ minTop;    

            //   double offsetX = minLeft - s *((canvas.ActualWidth - leftDis)/2);

            //    //double OffsetY = minTop -  s *((canvas.ActualHeight - topDis)/2);
            //    double offsetY = canvas.ActualWidth / 2 - midPos;

            //   canvas.Offset = new System.Windows.Point(offsetX, offsetY);
            //}


        }

        private void ZoomIn()
        {
            var x = Math.Pow(2, 120 / 3.0 / Mouse.MouseWheelDeltaForOneLine);
            canvas.Scale *= x;

            var position = new Vector(canvas.ActualWidth / 2, canvas.ActualHeight / 2);
            canvas.Offset = (System.Windows.Point)((Vector)(canvas.Offset + position) * x - position);
        }

        private void ZoomOut()
        {
            var x = Math.Pow(2, -120 / 3.0 / Mouse.MouseWheelDeltaForOneLine);
            canvas.Scale *= x;

            var position = new Vector(canvas.ActualWidth / 2, canvas.ActualHeight / 2);
            canvas.Offset = (System.Windows.Point)((Vector)(canvas.Offset + position) * x - position);
        }

        //private void canvas_MouseWheel(object sender, MouseWheelEventArgs e)
        //{
        //    var x = Math.Pow(2, e.Delta / 3.0 / Mouse.MouseWheelDeltaForOneLine);
        //    canvas.Scale *= x;

        //    // Adjust the offset to make the point under the mouse stay still.
        //    System.Windows.Point LastMousePosition = e.GetPosition(this);
        //    var position = (Vector)LastMousePosition;
        //    canvas.Offset = (System.Windows.Point)((Vector)(canvas.Offset + position) * x - position);
        //}

        protected override  void OnMouseWheel(MouseWheelEventArgs e)
        {
            var x = Math.Pow(2, e.Delta / 3.0 / Mouse.MouseWheelDeltaForOneLine);
            canvas.Scale *= x;

            // Adjust the offset to make the point under the mouse stay still.
            var position = (Vector)e.GetPosition(this);
            canvas.Offset = (System.Windows.Point)((Vector)(canvas.Offset + position) * x - position);


        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            var height = this.canvas.ActualHeight + FirstRowHeight.Height.Value;
            System.Windows.Point position = e.GetPosition(this);
            lastPosition = position;
            CoordinatesTextBlock.Text = $"坐标：X: {position.X:F3}mm, Y: {height - position.Y:F3}mm";
        }


        private void AutoFill_Click(object sender, RoutedEventArgs e)
        {
            Autofill();
        }


        private void GeneratorItemSource(Dictionary<Type, List<PathEntityBase>> dxfDictionary)
        {
            List<PathEntityBase> combinedList = dxfDictionary.SelectMany(entry => entry.Value).ToList();

            // 使用自定义比较器对列表进行排序  
            // combinedList.Sort(new Vector3XYDistanceComparer());

           // var sortList = Utility.SortPathsGreedy(combinedList);

            PathListView.ItemsSource = combinedList;
            //foreach (var kvp in dxfDictionary)
            //{
               
                //if (kvp.Key.Name == EntityType.Arc.ToString())
                //{                  
                //    ArcListView.ItemsSource = kvp.Value;
                //}
                //else if (kvp.Key.Name == EntityType.Line.ToString())
                //{
                //    LineListView.ItemsSource = kvp.Value;
                //}
                //else if (kvp.Key.Name == EntityType.Circle.ToString())
                //{
                //    CircleListView.ItemsSource = kvp.Value;
                //}
           // }
        }


        private void GenerateColumns()
        {

            GenerateColumnsName(pathPropertyNames, PathGridView);

          
         
        }


        private void GenerateColumnsName(List<string> names,GridView gridView)
        {
            foreach (var header in names)
            {
                if (header.Contains("Center") || header.Contains("Point"))
                {
                    var column = new GridViewColumn
                    {
                        Header = header,
                        DisplayMemberBinding = new Binding(header)
                        {
                            Converter = new Vector3ToStringConverter()
                        }
                    };
                    gridView.Columns.Add(column);
                }

                else
                {
                    var column = new GridViewColumn
                    {
                        Header = header, // 假设 header 是列名的字符串  
                        DisplayMemberBinding = new Binding(header)
                        {

                            StringFormat = "F3" // 设置格式为固定点表示法，并带有3位小数  
                        }
                    };

                    gridView.Columns.Add(column);
                }

            }
        }
        public static List<string> GetPropertyNames(object obj)
        {
            List<string> propertyNames = new List<string>();
            PropertyInfo[] properties = obj.GetType().GetProperties();
            foreach (PropertyInfo property in properties)
            {
                if (System.Attribute.IsDefined(property, typeof(DisPlayPropertyAttribute)))
                {
                    propertyNames.Add(property.Name);
                }
            }
            return propertyNames;
        }

        private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
        {
            // 获取鼠标点击位置
            System.Windows.Point clickPoint = e.GetPosition(canvas);

             HitTestResult result = VisualTreeHelper.HitTest(canvas, clickPoint);
            if (result != null)
            {
                DependencyObject visualHit = result.VisualHit;
                System.Windows.Shapes.Shape? shape = visualHit as System.Windows.Shapes.Shape;

                if (shape != null)
                {
                    string? handle = shape.Tag.ToString();
                    if (handle != null)
                    {
                        foreach (PathEntityBase entity in PathListView.Items)
                        {
                            if (handle != null && handle == entity.Handle)
                            {
                                PathListView.SelectedItem = entity;
                                
                                PathListView.ScrollIntoView(entity);
                                break; // 找到后退出循环  
                            }
                        }
                    }
                    
                }
            }

           
        }

       
        private void canvas_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            // 获取鼠标点击位置
            System.Windows.Point clickPoint = e.GetPosition(canvas);

            HitTestResult result = VisualTreeHelper.HitTest(canvas, clickPoint);
            if (result != null)
            {
                DependencyObject visualHit = result.VisualHit;
                System.Windows.Shapes.Shape? shape = visualHit as System.Windows.Shapes.Shape;

                if (shape != null)
                {
                    string? handle = shape.Tag.ToString();
                    if (handle != null)
                    {
                        foreach (PathEntityBase entity in PathListView.Items)
                        {
                            if (handle != null && handle == entity.Handle)
                            {
                                PathListView.SelectedItem = entity;

                                PathListView.ScrollIntoView(entity);

                                // 根据用户右击的曲线执行操作
                                var contextMenu = new ContextMenu();

                                var bePunchPointMenu = new MenuItem();
                                bePunchPointMenu.Header = "选中为打孔点";
                                bePunchPointMenu.Click += (s, args) =>
                                {
                                    entity.IsPunchPoint = true;
                                    SetEntityPunchPoint(EntitiesWithPaths, handle, true);

                                    GeneratorItemSource(EntitiesWithPaths);
                                };

                                var beVisionPointMenu = new MenuItem();
                                beVisionPointMenu.Header = "选中为特征点";
                                beVisionPointMenu.Click += (s, args) =>
                                {
                                    entity.IsVisionPoint = true;
                                    SetEntityVisionPoint(EntitiesWithPaths, handle, true);

                                    GeneratorItemSource(EntitiesWithPaths);
                                };

                                var cancelBePunchPoint = new MenuItem();
                                cancelBePunchPoint.Header = "取消作为打孔点";
                                cancelBePunchPoint.Click += (s, args) =>
                                {
                                    entity.IsPunchPoint = false;
                                    SetEntityPunchPoint(EntitiesWithPaths, handle, false);

                                    GeneratorItemSource(EntitiesWithPaths);
                                };

                                var cancelBeVisionPointMenu = new MenuItem();
                                cancelBeVisionPointMenu.Header = "取消作为特征点";
                                cancelBeVisionPointMenu.Click += (s, args) =>
                                {
                                    entity.IsVisionPoint = false;

                                    SetEntityVisionPoint(EntitiesWithPaths, handle, false);

                                    GeneratorItemSource(EntitiesWithPaths);
                                };


                                var beCuttingPointMenu = new MenuItem();
                                beCuttingPointMenu.Header = "选中为切割点";
                                beCuttingPointMenu.Click += (s, args) =>
                                {
                                    entity.IsCuttingPoint = true;
                                    SetEntityCuttingPoint(EntitiesWithPaths, handle, true);

                                    GeneratorItemSource(EntitiesWithPaths);
                                };

                                var cancelBeCuttingPointMenu = new MenuItem();
                                cancelBeCuttingPointMenu.Header = "取消作为切割点";
                                cancelBeCuttingPointMenu.Click += (s, args) =>
                                {
                                    entity.IsVisionPoint = false;

                                    SetEntityCuttingPoint(EntitiesWithPaths, handle, false);

                                    GeneratorItemSource(EntitiesWithPaths);
                                };

                                if (entity.IsPunchPoint)
                                {
                                    contextMenu.Items.Add(cancelBePunchPoint);
                                }
                                else if (!entity.IsPunchPoint && entity is CirclePathEntity)
                                {
                                    contextMenu.Items.Add(bePunchPointMenu);
                                }

                                if (entity.IsVisionPoint)
                                {
                                    contextMenu.Items.Add(cancelBeVisionPointMenu);
                                }
                                else
                                {
                                    contextMenu.Items.Add(beVisionPointMenu);
                                }

                                if (entity.IsCuttingPoint)
                                {
                                    contextMenu.Items.Add(cancelBeCuttingPointMenu);
                                }
                                else
                                {
                                    contextMenu.Items.Add(beCuttingPointMenu);
                                }



                                contextMenu.IsOpen = true;

                                break; // 找到后退出循环  
                            }
                        }
                    }

                }
            }
        }


        private void SetEntityPunchPoint(Dictionary<Type, List<PathEntityBase>> dic, string handle, bool value)
        {
            foreach (var entityBases in dic.Values)
            {
                foreach (var enti in entityBases)
                {
                    if (handle == enti.Handle)
                    {
                        enti.IsPunchPoint = value;
                    }
                }


            }
        }


        private void SetEntityCuttingPoint(Dictionary<Type, List<PathEntityBase>> dic, string handle, bool value)
        {
            foreach (var entityBases in dic.Values)
            {
                foreach (var enti in entityBases)
                {
                    if (handle == enti.Handle)
                    {
                        enti.IsCuttingPoint = value;
                    }
                }


            }
        }

        private void SetEntityVisionPoint(Dictionary<Type, List<PathEntityBase>> dic, string handle, bool value)
        {
            foreach (var entityBases in dic.Values)
            {
                foreach (var enti in entityBases)
                {
                    if (handle == enti.Handle)
                    {
                        enti.IsVisionPoint = value;
                    }
                }


            }
        }


        private string[] GetVisionPointHandle(Dictionary<Type, List<PathEntityBase>> dic)
        {
            List<string> visionPoints = new List<string>(); 
            foreach (var entityBases in dic.Values)
            {
                foreach (var enti in entityBases)
                {
                    if (enti.IsVisionPoint && enti.Handle !=null)
                    {
                        visionPoints.Add(enti.Handle);
                    }
                }

            }

            return visionPoints.ToArray();
        }

        private string[] GetPunchPointHandle(Dictionary<Type, List<PathEntityBase>> dic)
        {
            List<string> visionPoints = new List<string>();
            foreach (var entityBases in dic.Values)
            {
                foreach (var enti in entityBases)
                {
                    if (enti.IsPunchPoint && enti.Handle != null)
                    {
                        visionPoints.Add(enti.Handle);
                    }
                }

            }

            return visionPoints.ToArray();
        }


        private string[] GetCuttingPointHandle(Dictionary<Type, List<PathEntityBase>> dic)
        {
            List<string> cuttingPoints = new List<string>();
            foreach (var entityBases in dic.Values)
            {
                foreach (var enti in entityBases)
                {
                    if (enti.IsCuttingPoint && enti.Handle != null)
                    {
                        cuttingPoints.Add(enti.Handle);
                    }
                }

            }

            return cuttingPoints.ToArray();
        }

        private void Apply_Click(object sender, RoutedEventArgs e)
        {
            if (_fileName is null)
            {
                MessageBox.Show("未找到文件名！");
                return;
            }
            DxfCharacterModel dxfCharacterModel = new DxfCharacterModel();

            dxfCharacterModel.ControlName = _fileName;

            dxfCharacterModel.VisionHandles = GetVisionPointHandle(EntitiesWithPaths);

            dxfCharacterModel.PunchesHandles = GetPunchPointHandle(EntitiesWithPaths);

            dxfCharacterModel.CuttingHandles = GetCuttingPointHandle(EntitiesWithPaths);

            SaveConfigData.SaveConfigNotWindow<DxfCharacterModel>(Paths.DxfConfigPaths, dxfCharacterModel);

        }

        private void LoadDxfCharacterModel()
        {
            var toolConfigs = ReadConfigData.GetParaConfigs<DxfCharacterModel>(Paths.DxfConfigPaths);
        }

        
    }
}
